<!-- 控件动画设置 -->
<template>
    <el-dialog
        v-model="showDialog"
        title="动画设置"
        width="773px"
        append-to-body
        destroy-on-close
    >
        <div class="animations-wrap">
            <div class="left-wrap not-select">
                <div class="left-add-btn" @click="onAddAnimation">
                    <el-icon><icon-add /></el-icon>
                    添加动画
                </div>
                <el-scrollbar v-if="animations.length > 0">
                    <div class="left-list">
                        <template v-for="(item, index) in animations" :key="index">
                            <div
                                :class="{ 'active': animationIndex === index }"
                                class="left-item"
                                @click="onSelectAnimation(index)"
                            >
                                <div class="left-item-title">
                                    动画{{ index + 1 }}
                                </div>
                                <div class="left-item-btn">
                                    <el-icon @click.stop="onDeleteAnimation(index)"><icon-delete /></el-icon>
                                </div>
                            </div>
                        </template>
                    </div>
                </el-scrollbar>
                <div v-else class="no-data-txt">暂无动画</div>
            </div>
            <div class="content-wrap">
                <el-scrollbar>
                    <div class="content-main">
                        <template v-if="!!animation">
                            <div class="row-wrap">
                                <div class="row-left">选择动画</div>
                                <div class="row-right">
                                    <el-select
                                        v-model="animation.name"
                                        placeholder="请选择动画"
                                        size="large"
                                        filterable
                                        style="width: 180px;"
                                    >
                                        <el-option-group
                                            v-for="(groupItem, groupIndex) in animationData"
                                            :key="groupIndex"
                                            :label="groupItem.label"
                                        >
                                            <el-option
                                                v-for="(item, index) in groupItem.data"
                                                :key="index"
                                                :label="item.label"
                                                :value="item.value"
                                            />
                                        </el-option-group>
                                    </el-select>
                                </div>
                            </div>

                            <div class="row-wrap">
                                <div class="row-left">开始时间</div>
                                <div class="row-right">
                                    <el-input-number
                                        v-model="animation.delay"
                                        :min="0"
                                        :max="10"
                                        :step="0.1"
                                        controls-position="right"
                                        size="large"
                                    />
                                </div>
                            </div>

                            <div class="row-wrap">
                                <div class="row-left">持续时间</div>
                                <div class="row-right">
                                    <el-input-number
                                        v-model="animation.duration"
                                        :min="0"
                                        :max="10"
                                        :step="0.1"
                                        controls-position="right"
                                        size="large"
                                    />
                                </div>
                            </div>
                            
                            <div class="row-wrap flex-start">
                                <div class="row-left">循环次数</div>
                                <div class="row-right">
                                    <el-radio-group
                                        :modelValue="(animation.count === Infinity) ? -1 : 1"
                                        @update:modelValue="val => animation.count = (val === -1 ? Infinity : val)"
                                    >
                                        <el-radio :label="1">限制次数</el-radio>
                                        <el-radio :label="-1">无数次</el-radio>
                                    </el-radio-group>

                                    <el-input-number
                                        v-if="animation.count !== Infinity"
                                        v-model="animation.count"
                                        :min="1"
                                        controls-position="right"
                                        size="large"
                                    />
                                </div>
                            </div>
                        </template>
                        <div v-else class="no-data-txt">暂无动画，左侧点击添加动画</div>
                    </div>
                </el-scrollbar>
            </div>
            <div class="right-wrap">
                <div class="right-header">动画效果</div>
                <div class="right-content">
                    <div
                        :style="animationStyle"
                        :class="animationClass"
                        class="right-preview"
                        @animationend="onAnimationEnd"
                    ></div>
                </div>
            </div>
        </div>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="handleCancel">取消</el-button>
                <el-button type="primary" @click="handleConfirm">确认</el-button>
            </span>
        </template>
    </el-dialog>
</template>

<script>
import { defineComponent, ref, computed, watch, onScopeDispose } from 'vue'
import { deepClone } from '@/libs/tools'
import bus from '@/libs/bus'
import animationData from './animation-data'
import { onOpenAnimationsSettingEvent } from './events'
export default defineComponent({
    name: 'WidgetAnimationsSetting',
    setup() {
        const showDialog = ref(false)
        
        const animations = ref([])
        const animationIndex = ref(0)
        const animationClass = ref('')
        const animationStyle = ref({})
        const animation = computed({
            get: () => animations.value[animationIndex.value],
            set: val => animations.value[animationIndex.value] = val
        })

        watch(animation,
            () => onAnimationStart(),
            { deep: true }
        )

        onOpenAnimationsSettingEvent(({ data = [], onConfirm, onCancel }) => {
            showDialog.value = true

            const newData = data.length > 0
                ? deepClone(data)
                : [{
                    name: '',
                    direction: '',
                    delay: 0.2,
                    duration: 1,
                    count: 1
                }]
            animationIndex.value = 0
            animationClass.value = ''
            animationStyle.value = {}
            animations.value = newData
            
            // 回调方法
            const confirm = () => {
                onConfirm?.(animations.value)
                showDialog.value = false
            }
            const cancel = () => {
                onCancel?.()
                showDialog.value = false
            }
            bus.on('widget-animations-setting-confirm', confirm)
            bus.on('widget-animations-setting-cancel', cancel)
            onScopeDispose(() => {
                bus.off('widget-animations-setting-confirm', confirm),
                bus.off('widget-animations-setting-cancel', cancel)
            })
        })

        // 动画开始
        const onAnimationStart = () => {
            if (!animation.value) return
            const {
                name = '',
                direction = '',
                delay = 0,
                duration = 0,
                count = 0
            } = animation.value
            animationClass.value = ''
            animationStyle.value = {}
            setTimeout(() => {
                animationClass.value = `animate__animated animate__${name + direction}`
                animationStyle.value = {
                    animationPlayState: 'running',
                    animationDelay: `${delay}s`,
                    animationDuration: `${duration}s`,
                    animationIterationCount: count === Infinity ? 'infinite' : count
                }
            }, 10)
        }
        // 动画结束
        const onAnimationEnd = () => {
            animationClass.value = ''
            animationStyle.value = {}
        }

        // 添加动画
        const onAddAnimation = () => {
            animations.value.push({
                name: '',
                direction: '',
                delay: 0.2,
                duration: 1,
                count: 1
            })
        }

        // 选中动画
        const onSelectAnimation = index => {
            animationIndex.value = index
        }

        // 删除动画
        const onDeleteAnimation = index => {
            animations.value.splice(index, 1)
        }

        // 取消
        const handleCancel = () => {
            bus.emit('widget-animations-setting-cancel')
        }
        // 确认修改
        const handleConfirm = () => {
            bus.emit('widget-animations-setting-confirm')
        }

        return {
            showDialog,

            animationData,

            animations,
            animationIndex,
            animation,
            animationClass,
            animationStyle,

            onAddAnimation,
            onAnimationEnd,
            onSelectAnimation,
            onDeleteAnimation,
            handleCancel,
            handleConfirm
        }
    }
})
</script>

<style lang="less" scoped>
@import './widget-animations-setting.less';
</style>